home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
dmove86
/
dmove86.c
< prev
next >
Wrap
Text File
|
1995-02-15
|
10KB
|
540 lines
/*
dmove86 Version 2.00c
Copyright (c) 1993,94 Delmonta
dmove86.c -- メインルーチン
*/
#define MAIN
#include<stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<ctype.h>
#include<signal.h>
#include"dmove86.h"
/*-----------------------------------変数------------------------------------*/
static unsigned Pagenum,Lastnum;/* ページ数・最終ページのエントリ数 */
static unsigned Page=0,Pos=0; /* 現在のページ番号とカーソル位置 */
static unsigned Selected=-1; /* 選択され反転表示されている番号 */
static int Ischanged = 0;
/*---------------------------------------------------------------------------*/
static int isok(void)
{
if (!Ischanged)
return 1;
rep:
switch (dm_errmes("\aデータを保存していません よろしいですか(y/n)"))
{
case 'N':
case 'n':
case '\033':
return 0;
case 'Y':
case 'y':
return 1;
default:
goto rep;
}
}
/*---------------------------------画面表示----------------------------------*/
static void putfilename(p) /* 画面にファイル名を表示 */
int p;
{
printf("\033[%d;%df ",p/6+3,(p%6)*13+1);
if (Page*96+p == Selected)
printf("\033[7"); /* 最後の'm'はまだつけない */
else
printf("\033[0");
if (Dirtbl[Page*96+p]->filename[0]=='\xe5')
printf("m::::::::.:::");
else
{
int i;
if (Dirtbl[Page*96+p]->attr & _A_SUBDIR)
printf(";32m"); /* ディレクトリは緑 */
else if (Dirtbl[Page*96+p]->attr & _A_VOLID)
printf(";35m"); /* ボリュームIDは紫 */
else if (Dirtbl[Page*96+p]->attr & _A_SYSTEM)
printf(";31m"); /* システムファイルは赤 */
else
printf(";37m"); /* そのほかは白 */
for (i=0 ; i<8 ; i++)
{
if (i==0 && Dirtbl[Page*96+p]->filename[0]==5)
putchar('\xe5');
else
putchar(Dirtbl[Page*96+p]->filename[i]);
}
putchar('.');
for (i=0 ; i<3 ; i++)
putchar(Dirtbl[Page*96+p]->extname[i]);
}
printf(" \n\033[0;37m");
}
static void putpage(n) /* ページ表示 */
int n; /* n!=0なら一度画面を消す */
{
int i;
printf("\033[3;1f");
if (n)
for (i=0 ; i<16 ; i++)
printf("\033[2K\n");
for (i=0 ; i<96 ; i++)
{
if (Page==Pagenum-1 && i==Lastnum)
break;
else
putfilename(i);
}
}
void putcursor(void)
{
static int oldx = -1,
oldy = -1;
if (oldx != -1)
{
printf("\033[%d;%df",oldy+3,oldx*13+1);
putchar(' ');
printf("\033[%d;%df",oldy+3,oldx*13+13+1);
putchar(' ');
}
oldx = Pos%6;
oldy = Pos/6;
printf("\033[%d;%df",oldy+3,oldx*13+1);
putchar('<');
printf("\033[%d;%df",oldy+3,oldx*13+13+1);
putchar('>');
}
/*----------------------------カーソル移動とキー入力-------------------------*/
static char movecursor(flag)
int flag; /* カーソル・スペース・ESC以外を受け付けるか */
{
int c;
LOOP:
putcursor();
c = dm_getch();
if (c == '\3')
endscreen();
if (c == '\x1a')
endscreen();
switch (c)
{
case RIGHTKEY:
Pos++;
if (Pos==96 || (Page==Pagenum-1 && Pos==Lastnum) )
Pos=0;
break;
case LEFTKEY:
if (Pos==0)
{
if (Page==Pagenum-1)
Pos = Lastnum-1;
else
Pos = 95;
}
else
Pos--;
break;
case UPKEY:
if (Pos>=6)
Pos = Pos-6;
break;
case DOWNKEY:
if (Pos>=96-6 || (Page==Pagenum-1 && Pos+6>=Lastnum) )
; /* Pos>=Lastnum-6では、Lastnum-6<0となって */
else /* Posがunsignedの為正確に判断できない場合有 */
Pos = Pos+6;
break;
case '-':
if (Page>=1)
{
Page--;
putpage(1);
}
break;
case '+':
if (Page<Pagenum-1)
{
Page++;
if (Page==Pagenum-1 && Pos>=Lastnum)
Pos = Lastnum-1;
putpage(1);
}
break;
case ' ':
if (Dirtbl[Page*96+Pos]->filename[0]!='.')
return c;
else
dm_errmes("\".\"や\"..\"に対しては操作できません.\a");
break;
case '\033':
return c;
default:
if (flag)
return c;
break;
}
goto LOOP;
}
/*--------------------------------各コマンド---------------------------------*/
static void cmd_insert(void)
{
int i;
struct DIRENTRY far *d;
if ((d=Dirtbl[Dirnum-1])->filename[0]=='\xe5')
{
for (i=Dirnum-1 ; i>Page*96+Pos ; i--)
Dirtbl[i] = Dirtbl[i-1];
Dirtbl[Page*96+Pos] = d;
Ischanged = 1;
putpage(0);
}
else
putchar('\a');
}
static void cmd_delete(void)
{
int i;
struct DIRENTRY far *d;
if ((d=Dirtbl[Page*96+Pos])->filename[0]=='\xe5')
{
for (i=Page*96+Pos ; i<Dirnum-1 ; i++)
Dirtbl[i] = Dirtbl[i+1];
Dirtbl[Dirnum-1] = d;
Ischanged = 1;
putpage(0);
}
else
putchar('\a');
}
static void cmd_exchange(void)
{
int i;
struct DIRENTRY far *d;
Selected = Page*96+Pos;
putfilename(Pos);
if (movecursor(0)==' ' && Selected!=Page*96+Pos)
{
d = Dirtbl[Selected];
Dirtbl[Selected] = Dirtbl[Page*96+Pos];
Dirtbl[Page*96+Pos] = d;
Ischanged = 1;
}
if (Selected/96 == Page)
{
i = Selected%96;
Selected = -1;
putfilename(i);
}
else
Selected = -1;
putfilename(Pos);
}
static void cmd_sort(void)
{
Selected = Page*96+Pos;
putfilename(Pos);
printf( "\033[19;1f\033[37mソート:終点を指定してください\n");
if (movecursor(0)==' ' && Selected!=Page*96+Pos)
{
unsigned int s = Selected;
unsigned int e = Page*96+Pos;
if (s>e)
{
register unsigned int a = e;
e = s;
s = a;
}
if (dmsort(s,e))
Ischanged = 1;
}
printf("\033[19;1f\033[2K");
Selected = -1;
putpage(0);
}
static void cmd_help(void)
{
#define EL "\033[2K " /* 各行の行頭 */
#define AT "\033[36m" /* 水色 */
#define NO "\033[37m" /* 白に戻す */
printf( "\033[3;1f"
/* 0 */ EL "\n"
/* 1 */ EL " コマンドリスト\n"
/* 2 */ EL "\n"
/* 3 */ EL AT "[SPACE]" NO " 2つのファイルの位置を交換します\n"
/* 4 */ EL AT "H" NO "elp/" AT "[?]" NO " この画面を表示します\n"
/* 5 */ EL AT "D" NO "elete 空白を削除します\n"
/* 6 */ EL AT "I" NO "nsert 空白を挿入します\n"
/* 7 */ EL AT "R" NO "ename ファイル名等を変更します\n"
/* 8 */ EL AT "S" NO "ort エントリをソートします\n"
/* 9 */ EL AT "C" NO "hdir/" AT "[RET]" NO " サブディレクトリの中に入ります\n"
/* A */ EL AT "Q" NO "uit/" AT "[ESC]" NO " 親ディレクトリに戻ります\n"
/* B */ EL AT "O" NO "riginal 編集をやり直します\n"
/* C */ EL AT "W" NO "rite ディスクに編集結果を書き込みます\n"
/* D */ EL "\n"
/* E */ EL "\n"
/* F */ EL "\n");
#undef EL
#undef AT
#undef NO
dm_errmes("何かキーを押してください.");
putpage(1);
}
/*-------------------------------メインルーチン------------------------------*/
static void setglovalvar(struct DIRENTRY far **dirtbl,int dirnum)
{
Dirtbl = dirtbl;
Dirnum = dirnum;
Pagenum = dirnum/96;
Lastnum = dirnum%96;
if (Lastnum) Pagenum++;
else Lastnum = 96;
Page = 0;
Pos = 0;
Selected = -1;
Ischanged = 0;
}
void dmmenu(struct DIRENTRY far *parent)
{
struct DIRENTRY far *d;
struct SECTBL *sectbl;
auto int dirnum;
struct DIRENTRY far **dirtbl;
reread:
if ((dirtbl=readentry(parent,§bl,&dirnum))==NULL)
return;
setglovalvar(dirtbl,dirnum);
putpage(1);
dmmenu_loop:
switch (movecursor(1))
{
case 'H':
case 'h':
case '?':
cmd_help();
break;
case 'I':
case 'i':
cmd_insert();
break;
case 'D':
case 'd':
cmd_delete();
break;
case ' ':
cmd_exchange();
break;
case 'S':
case 's':
cmd_sort();
break;
case 'R':
case 'r':
if (Dirtbl[Page*96+Pos]->filename[0]=='\xe5')
break;
Selected = Page*96+Pos;
putfilename(Pos);
if (dmrename(Selected))
Ischanged = 1;
Selected = -1;
putfilename(Pos);
break;
case 'C':
case 'c':
case '\r':
d = dirtbl[Page*96+Pos];
if (d->attr&_A_SUBDIR && d->filename[0]!='.')
{
int ischanged_save = Ischanged;
int pagesave = Page;
int possave = Pos;
dmmenu(d);
setglovalvar(dirtbl,dirnum);
Page = pagesave;
Pos = possave;
Ischanged = ischanged_save;
putpage(1);
}
break;
case 'O':
case 'o':
if (isok())
{
freesectbl(sectbl);
free(dirtbl);
goto reread;
}
break;
case 'Q':
case 'q':
case '\033':
if (isok())
{
freesectbl(sectbl);
free(dirtbl);
return;
}
break;
case 'W':
case 'w':
writedir(sectbl,dirtbl);
Ischanged = 0;
break;
default:
putchar('\a');
}
goto dmmenu_loop;
}
/*------------------------------スタートアップ-------------------------------*/
#ifdef CTRLC_BUG /* LSI C-86の無印Ver3.30はSIG_IGNの処理にバグがある */
static void CTRLC_HANDLER(void)
{
signal(SIGINT,CTRLC_HANDLER);
}
#else
#define CTRLC_HANDLER SIG_IGN
#endif
int main(int argc,char **argv)
{
int c;
if (argc != 2)
{
rep:
printf("ドライブ名は:");
c = dm_getch();
if (c=='\033')
exit(0);
else if (!isalpha(c))
{
putchar('\n');
goto rep;
}
putchar(c);
putchar('\n');
}
else
c = argv[1][0];
Drive = toupper(c) - 'A';
if (Drive<0 || Drive>25)
{ printf("不正なドライブ名です.\n");
exit(2);
}
if (getdpb() == -1)
{ printf("指定されたドライブは存在しません.\n");
exit(2);
}
Fat = getfat();
if (Fat == NULL)
{ printf("FATの読み込みに失敗しました.\n");
exit(3);
}
signal(SIGINT,CTRLC_HANDLER);
mkscreen();
dmmenu(NULL);
endscreen();
}
void endscreen(void)
{
getdpb(); /* DOS内部のバッファを更新するため */
printf( "\033[0v\033[>5l\033[2J"
"DMOVE86を終了しました.\n");
exit(0);
}